using System;
using System.ComponentModel;

namespace SharpMud.Server.Systems
{
	/// <summary>
	/// This provides some of the most trivial sections of code for a standard subsystem that wants
	/// to implement IServerSystem. A derived server system may need only to plug into the stubs
	/// it uses.
	/// </summary>
	public class StandardServerSystemBase : IServerSystem
	{
		#region Private Variables
		private IServerSystemHost  _Host;
		private ServerSystemStatus __Status;
		#endregion

		#region Constructors
		public StandardServerSystemBase()
		{
			this._Status = ServerSystemStatus.Uninitialized;
		}
		#endregion

		#region IServerSystem Members

		protected virtual void _Initialize() {}
		public void Initialize(IServerSystemHost host)
		{
			this._Status = ServerSystemStatus.Initializing;
			this._Host = host;
			_Initialize();
			this._Status = ServerSystemStatus.Initialized;
		}

		protected virtual void _Start() {}
		public void Start()
		{
			this._Status = ServerSystemStatus.Starting;
			_Start();
			this._Status = ServerSystemStatus.Running;
		}

		protected virtual void _Pause() {}
		public void Pause()
		{
			this._Status = ServerSystemStatus.Pausing;
			_Pause();
			this.__Status = ServerSystemStatus.Paused;
		}

		protected virtual void _Resume() {}
		public void Resume()
		{
			this._Status = ServerSystemStatus.Resuming;
			_Resume();
			this.__Status = ServerSystemStatus.Running;
		}

		protected virtual void _Stop() {}
		public void Stop()
		{
			this._Status = ServerSystemStatus.Stopping;
			_Stop();
			this._Status = ServerSystemStatus.Stopped;
		}

		protected virtual void _Dispose() {}
		public void Dispose()
		{
			this._Status = ServerSystemStatus.Disposing;
			_Dispose();
			this._Status = ServerSystemStatus.Disposed;
		}

        [Browsable(true), DisplayName("Status"), Description("The server system's Status."), ReadOnly(true)]
		public ServerSystemStatus Status
		{
			get
			{
				return this.__Status;
			}
		}

		private event EventHandler<ServerSystemStatusChangeEventArgs> _StatusChanged;
        [Browsable(false)]
        public event EventHandler<ServerSystemStatusChangeEventArgs> StatusChanged
		{
			add
			{
				_StatusChanged += value;
			}
			remove
			{
				_StatusChanged -= value;
			}
		}

		#endregion

		#region Properties
        [Browsable(false)]
		public IServerSystemHost Host
		{
			get
			{
				return _Host;
			}
		}

		private ServerSystemStatus _Status
		{
			get
			{
				return this.__Status;
			}
			set
			{
				if(this.__Status!=value)
				{
					ServerSystemStatus o=this.__Status;
					this.__Status = value;
					if(this._StatusChanged!=null)
						_StatusChanged(this,new ServerSystemStatusChangeEventArgs(o,this.__Status));
				}
			}
		}
		#endregion

		#region Misc Methods
		protected void RequireServerSystemState(ServerSystemStatus requiredServerSystemStatus)
		{
			if(this.Status!=requiredServerSystemStatus)
				throw new InvalidOperationException("The given server system must be in the state of '" + requiredServerSystemStatus.ToString() + "' in order to perform the given operation.");
		}
		#endregion
	}
}
